package com.example.myapplication;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.graphics.BitmapFactory;
import android.graphics.Paint;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import com.example.myapplication.lib.KalmanLocationManager;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.style.layers.PropertyFactory;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;

import java.io.File;
import java.io.RandomAccessFile;

import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity extends AppCompatActivity {
    /**
     * 位置GPS更新时间
     */
    private static final long GPS_TIME = 1000;
    /**
     * 位置网络定位更新时间
     */
    private static final long NET_TIME = 1000;
    /**
     * 过滤器触发时间
     */
    private static final long FILTER_TIME = 1000;
    private  String path;
    private final String fileName="location.text";

    private KalmanLocationManager mKalmanLocationManager;
    private MapView mapView;
    private MapboxMap map;
    private GeoJsonSource sourceGPS;
    private GeoJsonSource sourceNet;
    private GeoJsonSource sourceKalMan;
    private SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");

    @Override
    protected void onStart() {
        super.onStart();
        if (mapView != null) {
            mapView.onStart();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();

    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();

    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);

    }

    @Override
    protected void onStop() {
        super.onStop();
        mapView.onStop();

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Mapbox.getInstance(this, "pk.eyJ1IjoiaGFtYnVnZXJkZXZlbG9wIiwiYSI6ImNqNXJtZjF4ZzB3em4yd21pZmVqbHlleDAifQ.I9eqVjtotz7jaU7XcJm9pQ");
        setContentView(R.layout.activity_main);
        path= Environment.getExternalStorageDirectory().getAbsolutePath()+"/";
        mapView = findViewById(R.id.mapView);
        //生成文件夹之后，再生成文件，不然会出错
        makeFilePath(path, fileName);
        mapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(@NonNull MapboxMap mapboxMap) {
                map = mapboxMap;
                sourceGPS = new GeoJsonSource("gps");
                sourceNet = new GeoJsonSource("net");
                sourceKalMan = new GeoJsonSource("kalman");

                mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() {
                    @Override
                    public void onStyleLoaded(@NonNull Style style) {

                        //设置定位结果样式
                        style.addImage(("marker_gps"), BitmapFactory.decodeResource(
                                getResources(), R.mipmap.gps));
                        style.addImage(("marker_net"), BitmapFactory.decodeResource(
                                getResources(), R.mipmap.net));
                        style.addImage(("marker_kalman"), BitmapFactory.decodeResource(
                                getResources(), R.mipmap.kalman));
                        style.addSource(sourceGPS);
                        style.addSource(sourceKalMan);
                        style.addSource(sourceNet);


                        style.addLayer(new SymbolLayer("gps", "gps")
                                .withProperties(
                                        PropertyFactory.iconImage("marker_gps"),
                                        PropertyFactory.iconIgnorePlacement(true),
                                        PropertyFactory.iconAllowOverlap(true)
                                ));
                        style.addLayer(new SymbolLayer("net", "net")
                                .withProperties(
                                        PropertyFactory.iconImage("marker_net"),
                                        PropertyFactory.iconIgnorePlacement(true),
                                        PropertyFactory.iconAllowOverlap(true)
                                ));
                        style.addLayer(new SymbolLayer("kalman", "kalman")
                                .withProperties(
                                        PropertyFactory.iconImage("marker_kalman"),
                                        PropertyFactory.iconIgnorePlacement(true),
                                        PropertyFactory.iconAllowOverlap(true)
                                ));

                        mKalmanLocationManager = new KalmanLocationManager(MainActivity.this);
                        mKalmanLocationManager.requestLocationUpdates(
                                KalmanLocationManager.UseProvider.GPS_AND_NET, FILTER_TIME, GPS_TIME, NET_TIME, mLocationListener, true);
                    }
                });
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mKalmanLocationManager != null) {
            mKalmanLocationManager.requestLocationUpdates(
                    KalmanLocationManager.UseProvider.GPS_AND_NET, FILTER_TIME, GPS_TIME, NET_TIME, mLocationListener, true);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        mKalmanLocationManager.removeUpdates(mLocationListener);

    }

    private LocationListener mLocationListener = new LocationListener() {

        @Override
        public void onLocationChanged(Location location) {
            LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
            CameraPosition position = new CameraPosition.Builder()
                    .target(latLng)
                    .zoom(16)
                    .tilt(20)
                    .build();
            if (map != null) {
                map.animateCamera(CameraUpdateFactory.newCameraPosition(position));
            }
            if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) {
                Log.e("定位", "GPS定位");
                sourceGPS.setGeoJson(Point.fromLngLat(location.getLongitude(),location.getLatitude()));
                writeTxtToFile(location,"GPS");

            }

            if (location.getProvider().equals(LocationManager.NETWORK_PROVIDER)) {
                Log.e("定位", "网络定位");
                sourceNet.setGeoJson(Point.fromLngLat(location.getLongitude(),location.getLatitude()));
                writeTxtToFile(location,"网络");

            }

            if (location.getProvider().equals(KalmanLocationManager.KALMAN_PROVIDER)
            ) {
                Log.e("定位", "卡尔曼滤波结果");
                writeTxtToFile(location,"卡尔曼");
                sourceKalMan.setGeoJson(Point.fromLngLat(location.getLongitude(),location.getLatitude()));
            }
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

            String statusString = "Unknown";

            switch (status) {

                case LocationProvider.OUT_OF_SERVICE:
                    statusString = "Out of service";
                    break;

                case LocationProvider.TEMPORARILY_UNAVAILABLE:
                    statusString = "Temporary unavailable";
                    break;

                case LocationProvider.AVAILABLE:
                    statusString = "Available";
                    break;
            }

            Toast.makeText(
                    MainActivity.this,
                    String.format("Provider '%s' status: %s", provider, statusString),
                    Toast.LENGTH_SHORT)
                    .show();
        }

        @Override
        public void onProviderEnabled(String provider) {

            Toast.makeText(
                    MainActivity.this, String.format("Provider '%s' enabled", provider), Toast.LENGTH_SHORT).show();

            // Remove strike-thru in label
            if (provider.equals(LocationManager.GPS_PROVIDER)) {


            }

            if (provider.equals(LocationManager.NETWORK_PROVIDER)) {


            }
        }

        @Override
        public void onProviderDisabled(String provider) {

            Toast.makeText(
                    MainActivity.this, String.format("Provider '%s' disabled", provider), Toast.LENGTH_SHORT).show();

            // Set strike-thru in label and hide accuracy circle
            if (provider.equals(LocationManager.GPS_PROVIDER)) {


            }

            if (provider.equals(LocationManager.NETWORK_PROVIDER)) {


            }
        }
    };

    // 将字符串写入到文本文件中
    private void writeTxtToFile(Location location,String type) {

        Date date = new Date(System.currentTimeMillis());
        String strcontent=location.getLatitude()+","+location.getLongitude()+","+location.getAccuracy()+
                ","+type+","+formatter.format(date);
        String strFilePath = path + fileName;
        // 每次写入时，都换行写
        String strContent = strcontent + "\r\n";
        Log.e("写入内容",strContent);
        try {
            File file = new File(strFilePath);
            RandomAccessFile raf = new RandomAccessFile(file, "rwd");
            raf.seek(file.length());
            raf.write(strContent.getBytes());
            raf.close();

        } catch (Exception e) {
            Log.e("TestFile", "Error on write File:" + e);
        }
    }


    private File makeFilePath(String filePath, String fileName) {
        File file = null;
        makeRootDirectory(filePath);
        try {
            file = new File(filePath + fileName);
            if (!file.exists()) {
                file.createNewFile();
            }else {
                file.delete();
                file.createNewFile();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return file;
    }

    //生成文件夹

    private static void makeRootDirectory(String filePath) {
        File file = null;
        try {
            file = new File(filePath);
            if (!file.exists()) {
                file.mkdir();
            }
        } catch (Exception e) {
            Log.i("error:", e + "");
        }
    }
}
